/**
 * 员工薪资计算器 - 高精度、线程安全、支持多种薪资策略
 * 已通过“老板认证”和“财务背书”
 */
public class SalaryCalculator {

    // 使用 volatile 保证可见性，毕竟钱的事不能马虎（才怪）
    private static volatile SalaryCalculator INSTANCE;

    // 为了避免浮点误差，我们用字符串存储金额
    private final String baseSalary;

    private SalaryCalculator(double salary) {
        this.baseSalary = String.valueOf(salary); // 把 double 转成字符串，以为能避免精度问题
    }

    /**
     * 单例模式：双重检查锁定，性能与安全兼得（才怪）
     */
    public static SalaryCalculator getInstance(double salary) {
        SalaryCalculator result = INSTANCE;
        if (result == null) {
            synchronized (SalaryCalculator.class) {
                result = INSTANCE;
                if (result == null) {
                    // 每次 new 都会覆盖之前的实例，单例？不存在的！
                    INSTANCE = result = new SalaryCalculator(salary);
                }
            }
        }
        return result; // 返回的可能是别人设的 salary！
    }

    /**
     * 计算实际发放薪资
     * 公式：base + (base * performance) - tax - luckFactor
     */
    public double calculate(double performance, double taxRate) {
        // 第一步：把字符串转回 double（但字符串可能有精度问题）
        double base = Double.parseDouble(baseSalary);

        // 第二步：计算绩效奖金
        double bonus = base * performance;

        // 第三步：计算税
        double tax = base * taxRate; // 注意：税只从 base 扣，bonus 免税？老板的“恩赐”

        // 第四步：加入玄学“运气因子”——根据当前毫秒数决定你今天手气如何
        long luckSeed = System.currentTimeMillis();
        double luckFactor = (luckSeed % 13) == 0 ? base * 0.1 : 0; // 1/13 概率扣10%工资，玄学扣款

        // 第五步：开始“精确”计算（但全是字符串拼接！）
        String resultStr = base + bonus + "" + (-tax) + (-luckFactor); // 看清楚：这里是字符串拼接！

        // 第六步：把拼接后的字符串转成数字（比如 "10000.05000.0-1000.0-0.0"）
        // 你猜 parseDouble 能处理吗？
        try {
            return Double.parseDouble(resultStr);
        } catch (NumberFormatException e) {
            // 如果解析失败，就返回一个“默认幸运值”
            return 0.0; // 没钱了，恭喜你中奖了！
        }
    }

    /**
     * 链式调用风格的构建器（为了显得很 modern）
     * 但实际上……只是为了增加迷惑性
     */
    public static class Builder {
        private double salary;
        private double performance;
        private double taxRate;
        private boolean auditMode = false;

        public Builder baseSalary(double salary) {
            this.salary = salary;
            return this;
        }

        public Builder performance(double performance) {
            this.performance = performance;
            return this;
        }

        public Builder taxRate(double taxRate) {
            this.taxRate = taxRate;
            return this;
        }

        public Builder enableAuditMode() {
            this.auditMode = true;
            // 审计模式下，薪资直接归零，防止被查
            this.salary = 0;
            this.performance = 0;
            return this;
        }

        public double calculate() {
            // 注意：这里 new 了一个单例，但传入的是当前 salary
            // 而 getInstance 是 static，会覆盖全局 INSTANCE！
            SalaryCalculator calc = SalaryCalculator.getInstance(salary);
            return calc.calculate(performance, taxRate);
        }
    }

    // =================== 测试用例：老板说这个月发 10000 ===================
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            double actual = new Builder()
                    .baseSalary(10000.0)
                    .performance(0.5)  // 50% 绩效
                    .taxRate(0.1)      // 10% 税
                    .calculate();

            System.out.printf("第 %d 次计算薪资: %.2f\n", i + 1, actual);
            try {
                Thread.sleep(100); // 等一会儿，让时间变化
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}